/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package me.zhengjie.modules.system.rest;

import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import me.zhengjie.annotation.AnonymousAccess;
import me.zhengjie.annotation.Log;
import me.zhengjie.config.FileProperties;
import me.zhengjie.config.enums.QrCodeTypeEnum;
import me.zhengjie.config.utils.QrCodeUtils;
import me.zhengjie.modules.system.domain.*;
import me.zhengjie.modules.system.domain.vo.BatchGroupTestDetailUserRespDTO;
import me.zhengjie.modules.system.service.*;
import me.zhengjie.modules.system.service.dto.*;
import me.zhengjie.modules.web.service.mybatisplus.IGroupTestDetailPlusService;
import me.zhengjie.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.MessageFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
* @website https://el-admin.vip
* @author zhaoxiancheng
* @date 2021-11-21
**/
@RestController
@RequiredArgsConstructor
@Api(tags = "团体测试二维码管理")
@RequestMapping("/api/groupTest")
public class GroupTestController {

    @Autowired
    FileProperties properties;

    @Value("${qrcode.url}")
    String qrCodeUrl;

    @Value("${qrcode.authUrl}")
    String qrAuthUrl;

    @Value("${qrcode.child_url}")
    String childQrCodeUrl;

    private final GroupTestService groupTestService;

    private final ExamResultService examResultService;

    @Autowired
    private AtmrService atmrService;

    @Autowired
    private GroupTestDetailService groupTestDetailService;

    @Autowired
    private IGroupTestDetailPlusService groupTestDetailPlusService;

    @Autowired
    private BatchGroupTestService batchGroupTestService;
    @Log("导出数据")
    @ApiOperation("导出数据")
    @GetMapping(value = "/download")
    @PreAuthorize("@el.check('groupTest:list')")
    public void download(HttpServletResponse response, GroupTestQueryCriteria criteria) throws IOException {
        groupTestService.download(groupTestService.queryAll(criteria), response);
    }

    @GetMapping
    @Log("查询团体测试二维码")
    @ApiOperation("查询团体测试二维码")
    @PreAuthorize("@el.check('groupTest:list')")
    public ResponseEntity<Object> query(GroupTestQueryCriteria criteria, Pageable pageable){
        criteria.setOptType(0);
        Map<String, Object> map = groupTestService.queryAll(criteria, pageable);
       /* if (MapUtil.isNotEmpty(map) && map.get("content") != null) {
            List<GroupTestDto> content = (List<GroupTestDto>) map.get("content");
            content.stream().forEach(s -> {
            });
        }*/
        return new ResponseEntity<>(map,HttpStatus.OK);
    }

    @RequestMapping("/batchList")
    @Log("查询批量团体测试二维码")
    @ApiOperation("查询批量团体测试二维码")
    @PreAuthorize("@el.check('groupTest:list')")
    public ResponseEntity<Object> batchList(GroupTestQueryCriteria criteria, Pageable pageable){
        criteria.setOptType(1);
        Map<String, Object> map = groupTestService.batchList(criteria, pageable);
        if (MapUtil.isNotEmpty(map) && map.get("content") != null) {
            List<GroupTestDto> content = (List<GroupTestDto>) map.get("content");
            content.stream().forEach(s -> {
                LambdaQueryWrapper<GroupTestDetail> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(GroupTestDetail::getGroupId,s.getId());
                List<GroupTestDetail> list = groupTestDetailPlusService.list(queryWrapper);
                if (CollectionUtils.isEmpty( list)){
                    return;
                }
                long count = list.stream().filter(f -> f.getTested() > 0 && f.getTested() < s.getLimitNum()).count();
                s.setTestedNotCompleteNum(count);
                long count1 = list.stream().filter(f -> f.getTested() == 0).count();
                s.setNotTestNum(count1);

                long count2 = list.stream().filter(f -> f.getTested().equals(s.getLimitNum())).count();
                s.setTestedCompleteNum(count2);

                int sum = list.stream().filter(f -> f.getTested() > 0).mapToInt(GroupTestDetail::getTested).sum();
                s.setTestedTotalNum(sum);
            });
        }
        return new ResponseEntity<>(map,HttpStatus.OK);
    }

    @RequestMapping("/batchDetail")
    @Log("查询批量团体测试详情")
    @ApiOperation("查询批量团体测试详情")
    @PreAuthorize("@el.check('groupTest:list')")
    public ResponseEntity<Object> batchDetail(@RequestBody BatchGroupTestDetailRequestDTO requestDTO){
        Page<BatchGroupTestDetailRespDTO> groupTestList = batchGroupTestService.batchDetail(requestDTO);
        return new ResponseEntity<>(groupTestList,HttpStatus.OK);
    }
    @RequestMapping("/batchUser")
    @Log("查询批量团体测试人员详情")
    @ApiOperation("查询批量团体测试人员详情")
    @PreAuthorize("@el.check('groupTest:list')")
    public ResponseEntity<Object> batchUser(@RequestBody BatchGroupTestDetailUserRequestDTO requestDTO){
        Page<BatchGroupTestDetailUserRespDTO> groupTestList = batchGroupTestService.batchUser(requestDTO);
        return new ResponseEntity<>(groupTestList,HttpStatus.OK);
    }

    @RequestMapping("/batchAllUser")
    @Log("查询批量团体测试全局查看详情")
    @ApiOperation("查询批量团体测试人员详情")
    //@PreAuthorize("@el.check('groupTest:list')")
    @AnonymousAccess
    public ResponseEntity<Object> batchAllUser(@RequestBody BatchGroupTestDetailUserRequestDTO requestDTO){
        Page<BatchGroupTestDetailUserRespDTO> groupTestList = batchGroupTestService.batchAllUser(requestDTO);
        return new ResponseEntity<>(groupTestList,HttpStatus.OK);
    }
    @PostMapping
    @Log("新增团体测试二维码")
    @ApiOperation("新增团体测试二维码")
    @PreAuthorize("@el.check('groupTest:add')")
    public ResponseEntity<Object> create(@Validated @RequestBody GroupTest resources){
        if (Objects.isNull(resources.getOptType())){
            resources.setOptType(0);
        }
        groupTestService.create(resources);
        AtmrDto atmrDto = atmrService.findById(resources.getAtmrId());
        String qrcodeUrl = qrCodeUrl;
        if (Objects.nonNull(atmrDto) && atmrDto.getAgeType().equals("2")){
            qrcodeUrl = childQrCodeUrl;
        }
        String content = MessageFormat.format(qrcodeUrl,resources.getAtmrId().toString(),resources.getId().toString());
        String codeUrl = QrCodeUtils.getInstance().generate(content, QrCodeTypeEnum.GroupTest);

        resources.setQrCode(codeUrl.replace(properties.getPath().getNgx(),""));
        groupTestService.update(resources);

        groupTestDetailService.batchInsert(resources,content);
        return new ResponseEntity<>(resources,HttpStatus.CREATED);
    }

    @PutMapping
    @Log("修改团体测试二维码")
    @ApiOperation("修改团体测试二维码")
    @PreAuthorize("@el.check('groupTest:edit')")
    public ResponseEntity<Object> update(@Validated @RequestBody GroupTest resources){
        groupTestService.updateV2(resources);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @Log("删除团体测试二维码")
    @ApiOperation("删除团体测试二维码")
    @PreAuthorize("@el.check('groupTest:del')")
    @DeleteMapping
    public ResponseEntity<Object> delete(@RequestBody Integer[] ids) {
        groupTestService.deleteAll(ids);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @GetMapping(value = "/queryAll")
    @Log("查询团体测试二维码列表")
    @ApiOperation("查询团体测试二维码列表")
    @PreAuthorize("@el.check('groupTest:list')")
    public ResponseEntity<Object> queryAll(GroupTestQueryCriteria criteria){
        return new ResponseEntity<>(groupTestService.queryAll(criteria),HttpStatus.OK);
    }

    @GetMapping("/get/report/{groupId}")
    @Log("查询团体测试报告整体分析")
    @ApiOperation("查询团体测试报告整体分析")
    @PreAuthorize("@el.check('groupTest:list')")
    public ResponseEntity<Object> getReportByGroupId(@PathVariable("groupId") String groupId){
        return new ResponseEntity<>(examResultService.countGroupByResultType(groupId),HttpStatus.OK);
    }

    @Log("导出团测报告")
    @ApiOperation("导出团测报告")
    @PostMapping(value = "/export")
    @PreAuthorize("@el.check('groupTest:list')")
    public void export(HttpServletResponse response, @RequestBody ExamResultExportRequest exportRequest) throws IOException {
        if(Objects.isNull(exportRequest.getGroupTestId())){
            return;
        }
        examResultService.exportGroupTestV2(exportRequest.getGroupTestId(), response);
    }
    @Log("导出批量测评码中全部报告")
    @ApiOperation("导出批量测评码中全部报告")
    @PostMapping(value = "/batchExportAll")
    @PreAuthorize("@el.check('groupTest:list')")
    public void batchExportAll(HttpServletResponse response, @RequestBody ExamResultExportRequest exportRequest) throws IOException {
        if(Objects.isNull(exportRequest.getGroupTestId())){
            return;
        }
        examResultService.exportGroupTestV2(exportRequest.getGroupTestId(), response);
    }
    @Log("导出批量团测二维码详情中报告")
    @ApiOperation("导出批量团测二维码详情中报告")
    @PostMapping(value = "/batchExport")
    @PreAuthorize("@el.check('groupTest:list')")
    public void batchExport(HttpServletResponse response, @RequestBody ExamResultExportRequest exportRequest) throws IOException {
        examResultService.batchExport(exportRequest.getGroupCode(), response);
    }

    @Log("导出团测二维码")
    @ApiOperation("导出团测二维码")
    @PostMapping(value = "/exportQrcode")
    @PreAuthorize("@el.check('groupTest:list')")
    public void exportQrcode(HttpServletResponse response, @RequestBody ExamResultExportRequest exportRequest) throws IOException {
        if(Objects.isNull(exportRequest.getGroupTestId())){
            return;
        }
        examResultService.exportGroupTestQrcode(exportRequest.getGroupTestId(), response);
    }

    @Log("导出测评码源数据")
    @ApiOperation("导出测评码源数据")
    @RequestMapping(value = "/downloadQrcode/{groupId}")
    //@PreAuthorize("@el.check('groupTest:list')")
    @AnonymousAccess
    public void downloadQrcode(HttpServletResponse response, @PathVariable("groupId") Long groupId) throws IOException {
        groupTestService.download(groupId, response);
    }

    @Log("导出批量码测评人员")
    @ApiOperation("导出批量码测评人员")
    @RequestMapping(value = "/exportTestingUser/{groupCode}")
    //@PreAuthorize("@el.check('groupTest:list')")
    @AnonymousAccess
    public void exportTestingUser(HttpServletResponse response, @PathVariable("groupCode") String groupCode) throws IOException {
        groupTestService.exportTestingUser(groupCode, response);
    }

    @Log("导出批量码测评人员")
    @ApiOperation("导出批量码测评人员")
    @RequestMapping(value = "/exportTestingUserV2/{groupId}")
    //@PreAuthorize("@el.check('groupTest:list')")
    @AnonymousAccess
    public void exportTestingUser(HttpServletResponse response, @PathVariable("groupId") Integer groupId) throws IOException {
        groupTestService.exportTestingUserV2(groupId, response);
    }
    @GetMapping(value = "/exportQrcode1")
    //@PreAuthorize("@el.check('groupTest:list')")
    @AnonymousAccess
    public void exportQrcode1(HttpServletResponse response) throws IOException {
        examResultService.exportGroupTestQrcode(1101, response);
    }
}